#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B38400
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

void signal_handler_IO (int status);    //definition of signal handler
int wait_flag=TRUE;                     //TRUE while no signal received
FILE *input;
FILE *output;
int status;

main()
{
	char Param_strings[7][80];
	char message[90];

	int fd, tty, c, res, i, error;
	char In1, Key;
	struct termios oldtio, newtio;       //place for old and new port settings for serial port
	struct termios oldkey, newkey;       //place tor old and new port settings for keyboard teletype
	struct sigaction saio;               //definition of signal action
	char buf[255];                       //buffer for where data is put

	input = fopen("/dev/tty", "r");      //open the terminal keyboard
	output = fopen("/dev/tty", "w");     //open the terminal screen

	tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_NONBLOCK); //set the user console port up
	tcgetattr(tty,&oldkey); // save current port settings   //so commands are interpreted right for this program
	// set new port settings for non-canonical input processing  //must be NOCTTY
	newkey.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
	newkey.c_iflag = IGNPAR;
	newkey.c_oflag = 0;
	newkey.c_lflag = 0;       //ICANON;
	newkey.c_cc[VMIN] = 1;
	newkey.c_cc[VTIME] = 0;
	tcflush(tty, TCIFLUSH);
	tcsetattr(tty,TCSANOW,&newkey);
            
	//open the device(com port) to be non-blocking (read will return immediately)
	fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NONBLOCK);

	//install the serial handler before making the device asynchronous
	saio.sa_handler = signal_handler_IO;
	sigemptyset(&saio.sa_mask);   //saio.sa_mask = 0;
	saio.sa_flags = 0;
	saio.sa_restorer = NULL;
	sigaction(SIGIO,&saio,NULL);

	// allow the process to receive SIGIO
	fcntl(fd, F_SETOWN, getpid());
	// Make the file descriptor asynchronous (the manual page says only
	// O_APPEND and O_NONBLOCK, will work with F_SETFL...)
	fcntl(fd, F_SETFL, FASYNC);

	tcgetattr(fd, &oldtio); // save current port settings 
	// set new port settings for canonical input processing 
	newtio.c_cflag = B9600 | CRTSCTS | CS8 | 0 | 0 | 0 | CLOCAL | CREAD;
	newtio.c_iflag = IGNPAR;
	newtio.c_oflag = 0;
	newtio.c_lflag = 0;       //ICANON;
	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd,TCSANOW,&newtio);

	// loop while waiting for input. normally we would do something useful here
	while (STOP==FALSE)
	{
		status = fread(&Key,1,1,input);
		if (status==1)  //if a key was hit
		{
            switch (Key)
            { /* branch to appropiate key handler */
				case 0x1b: /* Esc */
					STOP=TRUE;
				break;
				default:
					fputc((int) Key,output);
					write(fd,&Key,1);          //write 1 byte to the port
				break;
            }
		}
        
		if (wait_flag==FALSE)  //if input is available
		{
            res = read(fd,buf,255);
            if (res>0)
            {
				printf("%s\n", buf);
            }
            wait_flag = TRUE;      /* wait for new input */
		}

	}
	
	tcsetattr(fd,TCSANOW,&oldtio);
	tcsetattr(tty,TCSANOW,&oldkey);
	close(tty);
	close(fd);        //close the com port
   
	fclose(input);
	fclose(output);
}

void signal_handler_IO (int status)
{
	printf("received SIGIO signal.\r\n");
	wait_flag = FALSE;
}
